﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using HuaCheng.Model;

namespace HuaCheng.Controller
{
    //将缓冲区的包进行解析，分成720包和16包
    public class AnalysicBufferControl
    {
        /// <summary>
        /// 对缓冲区数据进行拆包
        /// </summary>
        /// <param name="bufferData"></param>
        /// <param name="recv"></param>
        /// <param name="ip"></param>
        /// <param name="queReceiveDic"></param>
        /// <param name="anaBufferModel"></param>
        public static void SplitSingleBag(byte[] bufferData, int recv, string ip, ConcurrentDictionary<string, ConcurrentQueue<string>> queReceiveDic, AnalysicBufferModel anaBufferModel, ConcurrentDictionary<string, ushort> countSeqDic, int id)
        {
            int head = 0;//定义一个指针
            //如果上一个缓冲区不是满的，包已经被取完,则从头开始读缓冲区
            if (!anaBufferModel.isFull)
            {
                if (recv == 720)//当recv刚好是720，则直接入队
                {
                    byte[] minBufferData = new byte[720];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 720);
                    //countSeqDic[ip]++;
                    //byte[] newByte = BitConverter.GetBytes(countSeqDic[ip]);
                    //minBufferData[718] = newByte[0];
                    //minBufferData[719] = newByte[1];
                    //queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "720" + ":" + ip);

                    //Console.WriteLine("1-ip:" + ip + "入队的包序：  " + BitConverter.ToUInt16(minBufferData, 718));
                    //string seqString = Convert.ToBase64String(minBufferData);                
                    //byte[] buffer = Convert.FromBase64String(seqString);
                    //Console.WriteLine("ip:" + ip + "出队的包序：  " + BitConverter.ToUInt16(buffer, 718));
                }
                else if (recv == 16)////当recv刚好是16，则直接入队
                {
                    byte[] minBufferData = new byte[16];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                    queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "16" + ":" + ip);
                    Console.WriteLine("入队16包1：  ");

                }
                //else if (recv == 0)//当recv刚好是0，则直接入队
                //{
                //    queReceiveDic[ip].Enqueue(Convert.ToBase64String(bufferData) + ":" + "0" + ":" + ip);
                //}
                else//循环遍历
                {
                    TravelBuffer(bufferData, ip, head, recv, anaBufferModel, queReceiveDic, countSeqDic, id);
                }
            }
            else//如果上一个缓冲区是满的，则需要根据上一个缓冲区最后一个包的情况先进行相应的合并操作
            {
                int lastLength = anaBufferModel.lastBag.Length;
                //将两个数组合并为一个数组
                byte[] newBufferData = new byte[lastLength + bufferData.Length];
                anaBufferModel.lastBag.CopyTo(newBufferData, 0);
                bufferData.CopyTo(newBufferData, lastLength);
                if (BitConverter.ToUInt16(newBufferData, head + 10) == 706)
                {
                    byte[] minBufferData = new byte[720];
                    if (newBufferData.Length >= 720)
                    {
                        Array.ConstrainedCopy(newBufferData, head, minBufferData, 0, 720);
                        head += 720;
                        //countSeqDic[ip]++;
                        //byte[] newByte = BitConverter.GetBytes(countSeqDic[ip]);
                        //minBufferData[718] = newByte[0];
                        //minBufferData[719] = newByte[1];
                        queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "720" + ":" + ip);
                        //Console.WriteLine("2-ip:" + ip + "入队的包序：  " + BitConverter.ToUInt16(minBufferData, 718) + "最后一个包：" + lastLength + "新缓冲区：" + newBufferData.Length + "第一个包：" + minBufferData.Length);
                        //for (int i = 0; i < minBufferData.Length - 1; i = i + 2)
                        //{
                        //    byte[] newMinBuff = new byte[2];
                        //    newMinBuff[0] = minBufferData[i];
                        //    newMinBuff[1] = minBufferData[i + 1];
                        //    Console.Write(BitConverter.ToUInt16(newMinBuff, 0) + " ");
                        //}
                        //Console.WriteLine();

                        //string seqString = Convert.ToBase64String(minBufferData);                
                        //byte[] buffer = Convert.FromBase64String(seqString);
                        //Console.WriteLine("ip:" + ip + "出队的包序：  " + BitConverter.ToUInt16(buffer, 718));
                    }                
                }
                //假如此时遍历读取的包是16包
                else if (BitConverter.ToUInt16(newBufferData, head + 10) == 2)
                {
                    byte[] minBufferData = new byte[16];
                    if (newBufferData.Length >= 16)
                    {
                        Array.ConstrainedCopy(newBufferData, head, minBufferData, 0, 16);
                        head += 16;
                        queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "16" + ":" + ip);
                        Console.WriteLine("入队16包2：  ");
                    }             
                }
                //循环遍历缓冲区剩余的所有数据
                TravelBuffer(newBufferData, ip, head, recv + lastLength, anaBufferModel, queReceiveDic, countSeqDic, id);
            }
        }

        /// <summary>
        /// 循环遍历缓冲区数据,进行拆包
        /// </summary>
        /// <param name="bufferData"></param>
        /// <param name="ip"></param>
        /// <param name="head"></param>
        /// <param name="recv"></param>
        /// <param name="anaBufferModel"></param>
        /// <param name="queReceiveDic"></param>
        public static void TravelBuffer(byte[] bufferData, string ip, int head, int recv, AnalysicBufferModel anaBufferModel, ConcurrentDictionary<string, ConcurrentQueue<string>> queReceiveDic, ConcurrentDictionary<string, ushort> countSeqDic, int id)
        {
            bool flag = false;//用来标志缓冲区已满并且末尾数据不完整，为false表示缓冲区未满或者缓冲区满了但是数据刚好完整，为true表示缓冲区已满并且末尾数据不完整。
            while (head < recv)
            {
                int diff = recv - head;//剩余数据量
                if (diff >= 720)
                {
                    //假如此时遍历读取的包是720包
                    if (BitConverter.ToUInt16(bufferData, head + 10) == 706)
                    {
                        byte[] minBufferData = new byte[720];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 720);
                        head += 720;
                        //countSeqDic[ip]++;
                        //byte[] newByte = BitConverter.GetBytes(countSeqDic[ip]);
                        //minBufferData[718] = newByte[0];
                        //minBufferData[719] = newByte[1];
                        queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "720" + ":" + ip);
                        //Console.WriteLine("id:" + id + "3-ip:" + ip + "入队的包序：  " + BitConverter.ToUInt16(minBufferData, 718));
                        //string seqString = Convert.ToBase64String(minBufferData);                
                        //byte[] buffer = Convert.FromBase64String(seqString);
                        //Console.WriteLine("ip:" + ip + "出队的包序：  " + BitConverter.ToUInt16(buffer, 718));
                    }
                    //假如此时遍历读取的包是16包
                    else if (BitConverter.ToUInt16(bufferData, head + 10) == 2)
                    {
                        byte[] minBufferData = new byte[16];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                        head += 16;
                        queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "16" + ":" + ip);
                        Console.WriteLine("入队16包3：  ");
                    }
                }
                else if ((diff >= 16) && (diff < 720))
                {
                    //假如此时遍历读取的包是720包,但是由于剩下的数据量不足720，则需要先将剩余的字节保存，与下一个缓冲区前面剩余的部分合并为一个包
                    if (BitConverter.ToUInt16(bufferData, head + 10) == 706)
                    {
                        byte[] minBufferData = new byte[diff];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, diff);
                        anaBufferModel.lastBagType = 720;
                        anaBufferModel.lastBag = minBufferData;
                        anaBufferModel.isFull = true;
                        flag = true;
                        break;
                    }
                    //假如此时遍历读取的包是16包
                    else if (BitConverter.ToUInt16(bufferData, head + 10) == 2)
                    {
                        byte[] minBufferData = new byte[16];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                        head += 16;
                        queReceiveDic[ip].Enqueue(Convert.ToBase64String(minBufferData) + ":" + "16" + ":" + ip);
                        Console.WriteLine("入队16包4：  ");
                    }
                }
                else if (diff < 16)
                {
                    byte[] minBufferData = new byte[diff];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, diff);
                    anaBufferModel.lastBagType = 0;//未知类型
                    anaBufferModel.lastBag = minBufferData;
                    anaBufferModel.isFull = true;
                    flag = true;
                    break;
                }

            }
            //如果缓冲区未满或者缓冲区刚好满了但是数据完整，则将isFull置为false
            if (!flag)
            {
                anaBufferModel.isFull = false;
            }
        }
    }
}
